﻿#pragma once
#include <thread>
#include <QMutex>
#include <mutex>
#include <condition_variable>
#include "ComponentBase.h"

class PathExcuteQueue;
class Pipeline;
class TaskInfoSql;
class PipelineCheckDlg;

class TaskProcess : public ComponentBase
{
	Q_OBJECT

public:
	TaskProcess(QObject* parent);
	~TaskProcess();
	bool PipelineErrorClear(Pipeline* p);
	QList<Pipeline*> GetPipeList();
	PathExcuteQueue* GetPathExcutor();

protected:
	// 组件初始化处理函数
	virtual int ComponentInit() override;
	/*自检接口*/
	virtual bool ComponentCheckSelfState() override;
	/*复位接口*/
	virtual bool ComponentSelfReset() override;
	/*系统状态响应接口*/
	virtual void ResponseSystemState(int state) override;
	virtual  void SetErrmsg(const QString& str, bool send = true) override;

	virtual bool ExcuteCmd(int cmd, const QByteArray& input, QByteArray& output) override;

private slots:
	void OnPathExcutedFailed(const QString& err);
	void TaskProcessStart();
private:
	void Sleep(int msec);
	// 数据库存储任务处理，软件第一次启动时执行
	void SendSqlTask();
	/*任务消息处理*/
	int OnDealWithTaskMsg(const QByteArray& data);

	/*抓托盘消息处理*/
	int OnDealWithPlateTaskMsg(const QByteArray& data);

	// 任务执行线程
	void TaskRunning();
	// 节拍执行线程
	void StepRunning();

	/*任务调度启动*/

	void TaskProcessStop();

	bool AddPipeToWarningQueue(Pipeline* p);
	bool AddPipeToPrepareQueue(Pipeline* p);
	bool AddPipeToExecQueue(Pipeline* p);
	bool MovePipeFromWarningQueue(Pipeline* p);
	bool MovePipeFromExecQueue(Pipeline* p);
	bool MovePipeFromPrepareQueue(Pipeline* p);


private:
	QMutex warningLock;
	QList<Pipeline*> m_warning;	 // 告警业务线队列
	QMutex prepareLock;
	QList<Pipeline*> m_prepare;		// 业务准备的业务线队列
	QMutex execLock;
	QList<Pipeline*> m_execqueue;	// 执行业务线队列
	QList<Pipeline*> m_pipelist;	// 所有

	std::mutex taskLock;		// 任务执行线程锁
	std::condition_variable taskCond;	// 任务执行线程条件变量
	std::thread* m_taskThread = nullptr;

	Pipeline* m_execPipe = nullptr;
	std::mutex stepLock;		// 任务执行线程锁
	std::condition_variable stepCond;	// 任务执行线程条件变量
	std::thread* m_stepThread = nullptr;


	PathExcuteQueue* m_pathExcute = nullptr;

	bool m_stop = true;  // 线程停止标志

	TaskInfoSql* m_sql = nullptr;

	PipelineCheckDlg* m_dlg = nullptr;
};
